/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import com.bourre.commands.Delegate;
import com.bourre.data.iterator.Iterator;

import fever.app.context.abstract.Dialog;
import fever.app.context.abstract.IDialog;
import fever.app.context.haxe.HaxeContext;
import fever.app.context.haxe.HaxeMethod;
import fever.data.file.FileFilter;
import fever.data.file.FileFilterCollection;
import fever.Fever;

import swhx.Api;

/**
 * Dialog system using <strong>Haxe</strong>.
 * 
 * <p>Usually <strong>Haxe</strong> work in synchronous mode.( result 
 * is directly return.<br />
 * But you can call alls these commands in Asynchronous mode, just adding 
 * the callback ( handler ) argument.
 *
 * @author Romain Ecarnot
 */
class fever.app.context.haxe.HaxeDialog extends Dialog implements IDialog
{
	//-------------------------------------------------------------------------
	// Public Properties
	//-------------------------------------------------------------------------
		
	/** Contstant. Haxe method name for showFileOpenDialog dialog method. */
	public static var showFileOpenDialogMETHOD : HaxeMethod = new HaxeMethod( 'showFileOpenDialog' );
	
	/** Contstant. Haxe method name for showFileSaveDialog dialog method. */
	public static var showFileSaveDialogMETHOD : HaxeMethod = new HaxeMethod( 'showFileSaveDialog' );
	
	/** Contstant. Haxe method name for showBrowseFolderDialog dialog method. */
	public static var showBrowseFolderDialogMETHOD : HaxeMethod = new HaxeMethod( 'showBrowseFolderDialog' );
	
	/** Contstant. Haxe method name for confirm dialog method. */
	public static var confirmMETHOD = new HaxeMethod( 'confirm' );
	
	/** Contstant. Haxe method name for message dialog method. */
	public static var alertMETHOD : HaxeMethod = new HaxeMethod( 'alert' );
	
	
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Constructor.
	 */
	public function HaxeDialog()
	{
		super();
	}
	
	/**
	 * Opens a File <strong>open</strong> chooser dialog.
	 * 
	 * @param caption ( optional ) Dialog's title
	 * @param filter ( optional ) File filter to apply ( default use All acceptable files *.* )
	 * @param multipleSelect ( optional ) {@code true} to enable multiple files selections in dialog
	 * @param ( optional ) handler Callback to activate when command is Asynchronous
	 * 
	 * @return The file or file(s) selected by the user.<br />
	 * When the multipleSelect option is enabled and multiple files are returned, the list of files 
	 * will be separated by a ";" character. <br />
	 * Returns {@code null} if no selection is available.
	 */
	public function showFileOpenDialog( caption : String, filterList : FileFilterCollection, multipleSelect : Boolean, handler : Delegate ) : String
	{
		if( !multipleSelect ) multipleSelect = false;
		
		var filter : Object = _parseFilter( filterList );
		var result : String = Api.call( 
			HaxeContext.getHaxeMethod( showFileOpenDialogMETHOD ), 
			caption, 
			filter, 
			multipleSelect 
		);
		
		if( result == 'null' ) result = null;
		if( handler == null ) return result;
		else
		{
			handler.addArguments( result );
			handler.execute();
		}
	}
	
	/**
	 * Opens a File <strong>save</strong> chooser dialog.
	 * 
	 * @param caption ( optional ) Dialog's title
	 * @param filter Not available in Haxe context
	 * @param fileName Not available in Haxe context
	 * @param ( optional ) handler Callback to activate when command is Asynchronous
	 * 
	 * @return A fully qualified file selected by the user ( or {@code null} )
	 */
	public function showFileSaveDialog( caption : String, filterList : FileFilterCollection, fileName : String, handler : Delegate ) : String
	{
		var result : String = Api.call( 
			HaxeContext.getHaxeMethod( showFileSaveDialogMETHOD ), 
			caption
		);
		
		if( result == 'null' ) result = null;
		if( handler == null ) return result;
		else
		{
			handler.addArguments( result );
			handler.execute();	
		}
	}
	
	/**
	 * Opens a Browse folder dialog.
	 * 
	 * @param caption ( optional ) Dialog's title
	 * @param ( optional ) handler Callback to activate when command is Asynchronous
	 * 
	 * @return The path to the selected folder ( or {@code null} )
	 */
	public function showBrowseFolderDialog( caption : String, handler : Delegate ) : String
	{
		var result : String = Api.call( 
			HaxeContext.getHaxeMethod( showBrowseFolderDialogMETHOD ), 
			caption
		);
		
		if( result == 'null' ) result = null;
		if( handler == null ) return result;
		else
		{
			handler.addArguments( result );
			handler.execute();	
		}
	}
	
	/**
	 * Opens a <strong>confirm</strong> dialog.
	 * 
	 * @param caption Dialog message
	 * @param ( optional ) handler Callback to activate when command is Asynchronous
	 * 
	 * @return {@code true} if user click on 'ok' button, otherwise {@code false}
	 */
	public function confirm( caption : String, handler : Delegate ) : Boolean
	{
		var result : Boolean =  Api.call( 
			HaxeContext.getHaxeMethod( confirmMETHOD ), 
			caption, 
			Fever.application.getTitle() 
		);
		
		if( handler == null ) return result;
		else
		{
			handler.addArguments( result );
			handler.execute();	
		}
	}
	
	/**
	 * Opens a <strong>alert</strong> dialog.
	 * 
	 * @param caption Dialog message
	 * @param ( optional ) handler Callback to activate when command is Asynchronous
	 */
	public function alert( caption : String, handler : Delegate ) : Void
	{
		Api.call( 
			HaxeContext.getHaxeMethod( alertMETHOD ), 
			caption, 
			Fever.application.getTitle(),
			true
		);
		
		if( handler ) handler.execute();
	}
	
	/**
	 * Opens a <strong>message</strong> dialog.
	 * 
	 * @param caption Dialog message
	 * @param ( optional ) handler Callback to activate when command is Asynchronous
	 */
	public function message( caption : String, handler : Delegate ) : Void
	{
		Api.call( 
			HaxeContext.getHaxeMethod( alertMETHOD ), 
			caption, 
			Fever.application.getTitle(),
			false
		);
		
		if( handler ) handler.execute();
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	/**
	 * Build compliant Haxe Systool filter.
	 */
	private function _parseFilter( filterList : FileFilterCollection ) : Object
	{
		var it : Iterator = filterList.getFilterIterator();
		var desc : Array = new Array();
		var ext : Array = new Array();
		
		while( it.hasNext() )
		{
			var filter : FileFilter = it.next();
			
			if( !filter.isEmpty() )
			{
				desc.push( filter.getDescription() );
				ext.push( filter.getString() );	
			}
		}
		
		var o : Object = new Object();
		o.length = desc.length;
		o.descriptions = desc;
		o.extensions = ext;
		
		return o;
	}	
}